#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <libxml/tree.h>
#include <libxml/parser.h>
#include "uim_ele_config.h"
#include "../can_uim.h"



int getNumEle(xmlNodePtr config_node, int * num_p_out, int * num_q_out)
{
   if(config_node==NULL)
   {
        return 0;
   }
   xmlAttrPtr numPropertyPtr = config_node->properties;
   xmlChar   * ptrContent = NULL;

   while(numPropertyPtr)
   {
	if(!xmlStrcmp(numPropertyPtr->name, BAD_CAST ("num_purify")))
	{
	    ptrContent = xmlNodeGetContent(numPropertyPtr->children);
	    if(ptrContent)
	    {
		* num_p_out = atoi((char *)ptrContent);
		printf("purify ele num:%d\n",*num_p_out);
		xmlFree(ptrContent);
	    } 
	}
	else  if(!xmlStrcmp(numPropertyPtr->name, BAD_CAST ("num_qpcr")))
	{
	    ptrContent = xmlNodeGetContent(numPropertyPtr->children);
	    if(ptrContent)
	    {
		* num_q_out = atoi((char *)ptrContent);
		printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    } 
	}
	numPropertyPtr = numPropertyPtr->next;
   }
   return 0;
       
}

int getOneConfig(xmlNodePtr eleNode, uim_ctl_desc * ptrEleCtlOut)
{
   if(eleNode==NULL)
   {
        return 0;
   }
   xmlNodePtr property_node = xmlFirstElementChild(eleNode);
   xmlChar   * ptrContent = NULL;

   while(property_node)
   {
	if(!xmlStrcmp(property_node->name, BAD_CAST ("sid")))
	{
	    ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->sid = atoi((char *)ptrContent);
		//printf("purify ele num:%d\n",*num_p_out);
		xmlFree(ptrContent);
	    } 
	}
	else  if(!xmlStrcmp(property_node->name, BAD_CAST ("ret_dir")))
	{
	    ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->ret_dir = atoi((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    } 
	}
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("ret_flag")))
        {
            
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		if(!xmlStrcmp(ptrContent, BAD_CAST ("up")))
                {
                    ptrEleCtlOut->retFlag = 0;
                }
                else if(!xmlStrcmp(ptrContent, BAD_CAST ("down")))
                {
                    ptrEleCtlOut->retFlag = 1;
                }
                else if(!xmlStrcmp(ptrContent, BAD_CAST ("no_ret")))
                {
                    ptrEleCtlOut->retFlag = 2;
                }
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    } 
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("status")))
        {            
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->status = atoi((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    } 
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("max_distance")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->max_distance = atoi((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("curr_pos")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->currPos = atoi((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("theta_perstep")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->thetaPerStep = atof((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("lead")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->lead = atof((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("lead")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
		ptrEleCtlOut->lead = atof((char *)ptrContent);
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        else if(!xmlStrcmp(property_node->name, BAD_CAST ("loop_type")))
        {
            ptrContent = xmlNodeGetContent(property_node);
	    if(ptrContent)
	    {
                if(!xmlStrcmp(ptrContent, BAD_CAST ("open_loop")))
                {
                    ptrEleCtlOut->loopType = 0;
                }
                else if(!xmlStrcmp(ptrContent, BAD_CAST ("close_loop")))
                {
                    ptrEleCtlOut->loopType = 1;
                }
		//printf("qpcr ele num:%d\n",*num_q_out);
		xmlFree(ptrContent);
	    }
        }
        
	property_node = property_node->next;
   }
   return 0;       
}

void readEleConfig(const char * fileName, int * numOut, void ** resultOut)
{
    xmlDocPtr pdoc = NULL; 

    xmlNodePtr proot = NULL;

    if(fileName==NULL)
    {
        return;
    }

    pdoc = xmlReadFile(fileName,"UTF-8",0);//xmlParseFile(fileNameIn);

    
    proot = xmlDocGetRootElement(pdoc);

    if (proot == NULL) 
    {
        printf("error: file[%s] is empty!\n",fileName);
        xmlFreeDoc(pdoc);
        return;
    }

    
    xmlNodePtr cur_node = proot;
    xmlNodePtr cur_node_child = cur_node;
    xmlChar   * ptrContent = NULL;
    int num_purify = 0;
    int num_qpcr = 0;
    int numGet=0;
    for (cur_node = proot; cur_node; cur_node = cur_node->next)
    {
 //       if (cur_node->type == XML_ELEMENT_NODE)
 //       {
 //           printf("node type: Element, name: %s\n", cur_node->name);
 //       }
 //       else if(cur_node->type == XML_TEXT_NODE)
 //       {
 //           printf("text: %s\n",xmlNodeGetContent(cur_node));//获取节点值
 //       }
        if (!xmlStrcmp(cur_node->name, BAD_CAST ("ele_ctl_uim")))
        {
            cur_node_child = xmlFirstElementChild(cur_node);
            while(cur_node_child)
            {
               if(!xmlStrcmp(cur_node_child->name, BAD_CAST ("config")))
	       {                    
                    getNumEle(cur_node_child, &num_purify, &num_qpcr);
                    //cur_node_child = cur_node_child->parent; 

                    if(num_purify>0)
                    {
                        uim_ctl_desc *  eleCtlArr =  new uim_ctl_desc[num_purify+num_qpcr];
                        memset(eleCtlArr,0,sizeof(uim_ctl_desc)*(num_purify+num_qpcr));
                        *resultOut = eleCtlArr;
                        uim_ctl_desc * ptrEleCtl = eleCtlArr;
                        xmlNodePtr ele_node = xmlFirstElementChild(cur_node_child);
                        
                        while(ele_node)
                        {                            
                            if(ele_node->type == XML_ELEMENT_NODE)
                            {
                                 getOneConfig(ele_node, ptrEleCtl);	                 
		                    
		                 ptrEleCtl ++; 
		                 numGet++;
		                 if(numGet>=(num_purify+num_qpcr))  
		                 {
		                    break;
		                 }  
                            }
                            else 
                            {
                               //printf("element type:%d, name:%s,content:%s\n",ele_node->type,ele_node->name,(char*)ele_node->content);
                           
                            }
                            ele_node = ele_node->next;
                                                    
                        }
                        
                    }                   		        
	       }
               cur_node_child = cur_node_child->next;
            }            
            
        }
    }

    * numOut = numGet;
    
    xmlFreeDoc(pdoc);

    xmlCleanupParser();
    xmlMemoryDump();
}



